package de.fhin.mas.agents.manager.behaviours;

import jade.core.Agent;
import jade.core.behaviours.Behaviour;
import jade.core.behaviours.FSMBehaviour;
import jade.core.behaviours.OneShotBehaviour;
import jade.domain.FIPANames;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import de.fhin.mas.MASEvents;
import de.fhin.mas.agents.manager.ManagerAgent;
import de.fhin.mas.ontology.Location;

/**
 * @deprecated
 */
@Deprecated
public class InitAbortAndGoTo extends FSMBehaviour {
	private static final long serialVersionUID = 1L;
	private ManagerAgent managerAgent;

	private Behaviour sendAbortCallBv = new OneShotBehaviour() {
		private static final long serialVersionUID = 1L;

		@Override
		public void action() {

			/**
			 * Content: Angabe des Resume Grundes
			 */
			String Content = "User wants Abort$Lager1";

			// "newOrder" Message = CFP Message
			ACLMessage AbortAndGoTo = new ACLMessage(ACLMessage.REQUEST);
			AbortAndGoTo.setContent(Content);
			AbortAndGoTo.setConversationId(MASEvents.ABORT_AND_GO_TO.getName());
			AbortAndGoTo.setProtocol(FIPANames.InteractionProtocol.FIPA_REQUEST);

			// Abschicken der Nachricht
			((ManagerAgent) myAgent).sendToAll(AbortAndGoTo);
		}

	};

	private Behaviour waitForAgreesBv = new Behaviour() {

		private static final long serialVersionUID = 1L;
		private int receivedAgrees = 0;
		private Integer doTransition = null;

		// private final Date startTime = new Date();

		@Override
		public void action() {
			MessageTemplate mt = MessageTemplate.and(MessageTemplate.MatchConversationId(MASEvents.ABORT_AND_GO_TO
					.getName()), MessageTemplate.or(MessageTemplate.MatchPerformative(ACLMessage.AGREE),
					MessageTemplate.MatchPerformative(ACLMessage.FAILURE)));

			managerAgent.logInfo("Waiting for AGREE or FAILURE or a timeout!");

			ACLMessage msg = myAgent.receive(mt);
			if (msg == null)
				block();
			else {
				if (msg.getPerformative() == ACLMessage.AGREE) {
					receivedAgrees++;
					managerAgent.logInfo("AbortAndGoTo agree received");
					if (receivedAgrees >= 3)
						doTransition = 1;
				} else if (msg.getPerformative() == ACLMessage.FAILURE)
					doTransition = 0;
			}
		}

		@Override
		public boolean done() {
			return doTransition != null;
		}

		@Override
		public int onEnd() {
			if (doTransition == 0) {
				managerAgent.logInfo("Transition to AbortAndGoTo_disagreed");

			} else if (doTransition == 1) {
				managerAgent.logInfo("Transition to AbortAndGoTo_agreed");

			}
			return doTransition;
		}
	};

	private Behaviour abortAndGoToExecutedBv = new OneShotBehaviour() {
		private static final long serialVersionUID = 1L;

		@Override
		public void action() {
			managerAgent.logInfo("State AbortAndGoTo_agreed reached.");

		}
	};

	private Behaviour abortAndGoToDisagreedBv = new OneShotBehaviour() {
		private static final long serialVersionUID = 1L;

		@Override
		public void action() {
			managerAgent.logInfo("State InitAbortAndGoTo_disagreed reached.");
			managerAgent.logInfo("InitSystemStop-Behaviour wird ausgelöst");

			// TODO: G`scheite Reason
			managerAgent.initSystemStop("abortAndGoToDisagreed");
		}
	};

	public InitAbortAndGoTo(Agent a, Location newTarget) {
		super(a);

		managerAgent = (ManagerAgent) a;

		registerFirstState(sendAbortCallBv, "AbortAndGoTo_init");
		registerState(waitForAgreesBv, "wait_for_agrees");
		registerLastState(abortAndGoToDisagreedBv, "AbortAndGoTo_disagreed");
		registerLastState(abortAndGoToExecutedBv, "AbortAndGoTo_executed");

		registerTransition("AbortAndGoTo_init", "wait_for_agrees", 0);
		registerTransition("wait_for_agrees", "AbortAndGoTo_disagreed", 0);
		registerTransition("wait_for_agrees", "AbortAndGoTo_executed", 1);
	}

}
